home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Resources / Developers / XAMPP 1.5.4 / Windows installer / xampp-win32-1.5.4-installer.exe / xampp / php / pear / Log / sql.php < prev    next >
Encoding:
PHP Script  |  2006-04-07  |  8.3 KB  |  288 lines

  1. <?php
  2. /**
  3.  * $Header: /repository/pear/Log/Log/sql.php,v 1.39 2005/10/25 16:42:53 jon Exp $
  4.  * $Horde: horde/lib/Log/sql.php,v 1.12 2000/08/16 20:27:34 chuck Exp $
  5.  *
  6.  * @version $Revision: 1.39 $
  7.  * @package Log
  8.  */
  9.  
  10. /** PEAR's DB package */
  11. require_once 'DB.php';
  12.  
  13. /**
  14.  * The Log_sql class is a concrete implementation of the Log::
  15.  * abstract class which sends messages to an SQL server.  Each entry
  16.  * occupies a separate row in the database.
  17.  *
  18.  * This implementation uses PHP's PEAR database abstraction layer.
  19.  *
  20.  * CREATE TABLE log_table (
  21.  *  id          INT NOT NULL,
  22.  *  logtime     TIMESTAMP NOT NULL,
  23.  *  ident       CHAR(16) NOT NULL,
  24.  *  priority    INT NOT NULL,
  25.  *  message     VARCHAR(200),
  26.  *  PRIMARY KEY (id)
  27.  * );
  28.  *
  29.  * @author  Jon Parise <jon@php.net>
  30.  * @since   Horde 1.3
  31.  * @since   Log 1.0
  32.  * @package Log
  33.  *
  34.  * @example sql.php     Using the SQL handler.
  35.  */
  36. class Log_sql extends Log
  37. {
  38.     /**
  39.      * Variable containing the DSN information.
  40.      * @var mixed
  41.      * @access private
  42.      */
  43.     var $_dsn = '';
  44.  
  45.     /**
  46.      * String containing the SQL insertion statement.
  47.      *
  48.      * @var string
  49.      * @access private
  50.      */
  51.     var $_sql = '';
  52.  
  53.     /**
  54.      * Array containing our set of DB configuration options.
  55.      * @var array
  56.      * @access private
  57.      */
  58.     var $_options = array('persistent' => true);
  59.  
  60.     /**
  61.      * Object holding the database handle.
  62.      * @var object
  63.      * @access private
  64.      */
  65.     var $_db = null;
  66.  
  67.     /**
  68.      * Resource holding the prepared statement handle.
  69.      * @var resource
  70.      * @access private
  71.      */
  72.     var $_statement = null;
  73.  
  74.     /**
  75.      * Flag indicating that we're using an existing database connection.
  76.      * @var boolean
  77.      * @access private
  78.      */
  79.     var $_existingConnection = false;
  80.  
  81.     /**
  82.      * String holding the database table to use.
  83.      * @var string
  84.      * @access private
  85.      */
  86.     var $_table = 'log_table';
  87.  
  88.     /**
  89.      * String holding the name of the ID sequence.
  90.      * @var string
  91.      * @access private
  92.      */
  93.     var $_sequence = 'log_id';
  94.  
  95.     /**
  96.      * Maximum length of the $ident string.  This corresponds to the size of
  97.      * the 'ident' column in the SQL table.
  98.      * @var integer
  99.      * @access private
  100.      */
  101.     var $_identLimit = 16;
  102.  
  103.  
  104.     /**
  105.      * Constructs a new sql logging object.
  106.      *
  107.      * @param string $name         The target SQL table.
  108.      * @param string $ident        The identification field.
  109.      * @param array $conf          The connection configuration array.
  110.      * @param int $level           Log messages up to and including this level.
  111.      * @access public
  112.      */
  113.     function Log_sql($name, $ident = '', $conf = array(),
  114.                      $level = PEAR_LOG_DEBUG)
  115.     {
  116.         $this->_id = md5(microtime());
  117.         $this->_table = $name;
  118.         $this->_mask = Log::UPTO($level);
  119.  
  120.         /* Now that we have a table name, assign our SQL statement. */
  121.         if (!empty($this->_sql)) {
  122.             $this->_sql = $conf['sql'];
  123.         } else {
  124.             $this->_sql = 'INSERT INTO ' . $this->_table .
  125.                           ' (id, logtime, ident, priority, message)' .
  126.                           ' VALUES(?, CURRENT_TIMESTAMP, ?, ?, ?)';
  127.         }
  128.  
  129.         /* If an options array was provided, use it. */
  130.         if (isset($conf['options']) && is_array($conf['options'])) {
  131.             $this->_options = $conf['options'];
  132.         }
  133.  
  134.         /* If a specific sequence name was provided, use it. */
  135.         if (!empty($conf['sequence'])) {
  136.             $this->_sequence = $conf['sequence'];
  137.         }
  138.  
  139.         /* If a specific sequence name was provided, use it. */
  140.         if (isset($conf['identLimit'])) {
  141.             $this->_identLimit = $conf['identLimit'];
  142.         }
  143.  
  144.         /* Now that the ident limit is confirmed, set the ident string. */
  145.         $this->setIdent($ident);
  146.  
  147.         /* If an existing database connection was provided, use it. */
  148.         if (isset($conf['db'])) {
  149.             $this->_db = &$conf['db'];
  150.             $this->_existingConnection = true;
  151.             $this->_opened = true;
  152.         } else {
  153.             $this->_dsn = $conf['dsn'];
  154.         }
  155.     }
  156.  
  157.     /**
  158.      * Opens a connection to the database, if it has not already
  159.      * been opened. This is implicitly called by log(), if necessary.
  160.      *
  161.      * @return boolean   True on success, false on failure.
  162.      * @access public
  163.      */
  164.     function open()
  165.     {
  166.         if (!$this->_opened) {
  167.             /* Use the DSN and options to create a database connection. */
  168.             $this->_db = &DB::connect($this->_dsn, $this->_options);
  169.             if (DB::isError($this->_db)) {
  170.                 return false;
  171.             }
  172.  
  173.             /* Create a prepared statement for repeated use in log(). */
  174.             if (!$this->_prepareStatement()) {
  175.                 return false;
  176.             }
  177.  
  178.             /* We now consider out connection open. */
  179.             $this->_opened = true;
  180.         }
  181.  
  182.         return $this->_opened;
  183.     }
  184.  
  185.     /**
  186.      * Closes the connection to the database if it is still open and we were
  187.      * the ones that opened it.  It is the caller's responsible to close an
  188.      * existing connection that was passed to us via $conf['db'].
  189.      *
  190.      * @return boolean   True on success, false on failure.
  191.      * @access public
  192.      */
  193.     function close()
  194.     {
  195.         if ($this->_opened && !$this->_existingConnection) {
  196.             $this->_opened = false;
  197.             $this->_db->freePrepared($this->_statement);
  198.             return $this->_db->disconnect();
  199.         }
  200.  
  201.         return ($this->_opened === false);
  202.     }
  203.  
  204.     /**
  205.      * Sets this Log instance's identification string.  Note that this
  206.      * SQL-specific implementation will limit the length of the $ident string
  207.      * to sixteen (16) characters.
  208.      *
  209.      * @param string    $ident      The new identification string.
  210.      *
  211.      * @access  public
  212.      * @since   Log 1.8.5
  213.      */
  214.     function setIdent($ident)
  215.     {
  216.         $this->_ident = substr($ident, 0, $this->_identLimit);
  217.     }
  218.  
  219.     /**
  220.      * Inserts $message to the currently open database.  Calls open(),
  221.      * if necessary.  Also passes the message along to any Log_observer
  222.      * instances that are observing this Log.
  223.      *
  224.      * @param mixed  $message  String or object containing the message to log.
  225.      * @param string $priority The priority of the message.  Valid
  226.      *                  values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
  227.      *                  PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
  228.      *                  PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
  229.      * @return boolean  True on success or false on failure.
  230.      * @access public
  231.      */
  232.     function log($message, $priority = null)
  233.     {
  234.         /* If a priority hasn't been specified, use the default value. */
  235.         if ($priority === null) {
  236.             $priority = $this->_priority;
  237.         }
  238.  
  239.         /* Abort early if the priority is above the maximum logging level. */
  240.         if (!$this->_isMasked($priority)) {
  241.             return false;
  242.         }
  243.  
  244.         /* If the connection isn't open and can't be opened, return failure. */
  245.         if (!$this->_opened && !$this->open()) {
  246.             return false;
  247.         }
  248.  
  249.         /* If we don't already have our statement object yet, create it. */
  250.         if (!is_object($this->_statement) && !$this->_prepareStatement()) {
  251.             return false;
  252.         }
  253.  
  254.         /* Extract the string representation of the message. */
  255.         $message = $this->_extractMessage($message);
  256.  
  257.         /* Build our set of values for this log entry. */
  258.         $id = $this->_db->nextId($this->_sequence);
  259.         $values = array($id, $this->_ident, $priority, $message);
  260.  
  261.         /* Execute the SQL query for this log entry insertion. */
  262.         $result =& $this->_db->execute($this->_statement, $values);
  263.         if (DB::isError($result)) {
  264.             return false;
  265.         }
  266.  
  267.         $this->_announce(array('priority' => $priority, 'message' => $message));
  268.  
  269.         return true;
  270.     }
  271.  
  272.     /**
  273.      * Prepare the SQL insertion statement.
  274.      *
  275.      * @return boolean  True if the statement was successfully created.
  276.      *
  277.      * @access  private
  278.      * @since   Log 1.9.1
  279.      */
  280.     function _prepareStatement()
  281.     {
  282.         $this->_statement = $this->_db->prepare($this->_sql);
  283.  
  284.         /* Return success if we didn't generate an error. */
  285.         return (DB::isError($this->_statement) === false);
  286.     }
  287. }
  288.